package com.ddxz.middleground.gateway.filter;

import com.ddxz.middleground.gateway.service.GatewayService;
import com.ddxz.tool.core.common.DdxzJwtUtil;
import com.ddxz.tool.core.convert.StringUtil;
import com.netflix.util.Pair;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.util.UrlPathHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * class description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2020/7/26
 */

@Component
public class DdxzPreFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String url = urlPathHelper.getPathWithinApplication(ctx.getRequest());
        AntPathMatcher pathMatcher = new AntPathMatcher();
        for (String pat : ANON_URL) {
            if (pathMatcher.match(pat, url)) {
                return false;
            }
        }

        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String token = ctx.getRequest().getHeader("Authorization");
        try {
            Map<String, Object> headers = jwtUtil.getBody(token);
            if(!service.isPermission(headers.get("roleIds").toString(), urlPathHelper.getPathWithinApplication(ctx.getRequest()))) {
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(403);
                ctx.setResponseBody("{\"status\":403,\"message\":\"无权执行该操作\"}");
                return null;
            }
            ctx.getZuulRequestHeaders().put("userId", headers.get("userId").toString());
            ctx.getZuulRequestHeaders().put("roleIds", headers.get("roleIds").toString());
            ctx.getZuulRequestHeaders().put("nickname", headers.get("nickname").toString());
            ctx.getZuulRequestHeaders().put("deptId", headers.get("deptId").toString());
            ctx.getZuulRequestHeaders().put("tenant", headers.get("tenant").toString());
            ctx.getZuulResponseHeaders().add(new Pair<>("Authorization", jwtUtil.getToken(headers, expired)));
        } catch (Exception e) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.setResponseBody("{\"status\":401,\"message\":\"无效的令牌\"}");
        }

        return null;
    }

    private UrlPathHelper urlPathHelper = new UrlPathHelper();
    private DdxzJwtUtil jwtUtil = new DdxzJwtUtil();
    private static final List<String> ANON_URL = new ArrayList<>();

    @Autowired
    private GatewayService service;

    private Long expired;

    @Value("${ddxz.token.expired}")
    public void setExpired(String expired) {
        this.expired = StringUtil.toLong(expired);
    }

    static {
        ANON_URL.add("/swagger-ui.html");
        ANON_URL.add("/webjars/springfox-swagger-ui/**");
        ANON_URL.add("/swagger-resources/**");
        ANON_URL.add("/v2/api-docs");
        ANON_URL.add("/login");
    }
}
